package com.xbongbong.paas.service.impl;

import com.alibaba.dingtalk.openapi.exception.OApiException;
import com.alibaba.dingtalk.openapi.helper.AuthHelper;
import com.alibaba.dingtalk.openapi.helper.Env;
import com.alibaba.dingtalk.openapi.helper.UserHelper;
import com.alibaba.dingtalk.openapi.utils.HttpHelper;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.SnsLoginService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.MD5Util;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.dingtalk.pojo.vo.SnsCompanyVO;
import com.xbongbong.pro.dingtalk.pojo.vo.SnsUserInfoVO;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.sys.domain.entity.CompanyEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.CompanyModel;
import com.xbongbong.sys.model.UserModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.xbongbong.paas.redis.RedisPrefixConstant.USER_INFO_DIGEST;

/**
 * 扫码登录业务实现
 * @author kaka
 * @version v1.0
 * @date 2019/5/29 16:48
 * @since v1.0
 */
@Service("snsLoginService")
public class SnsLoginServiceImpl implements SnsLoginService {

    private static final Logger LOG = LoggerFactory.getLogger(SnsLoginServiceImpl.class);

    @Resource
    private ProBaseConfig proBaseConfig;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private AuthHelper authHelper;
    @Resource
    private UserModel userModel;
    @Resource
    private CompanyModel companyModel;

    @Override
    public SnsUserInfoVO snsUserInfo(String code, String corpid) throws XbbException {
        SnsUserInfoVO snsUserInfoVO = new SnsUserInfoVO();
        try {
            //第三步
            String snsAccesstoken = authHelper.getSNSAccessToken(proBaseConfig.getScanAppId(), proBaseConfig.getScanAppSecret());
            //第四步
            String snsUrl4 = Env.OAPI_HOST + "/sns/get_persistent_code?access_token=" + snsAccesstoken ;
            JSONObject args = new JSONObject();
            args.put("tmp_auth_code",code);
            JSONObject snsResponse = HttpHelper.httpPost(snsUrl4, args);

            String openid = snsResponse.getString("openid");
            String persistentCode = snsResponse.getString("persistent_code");

            //第五步
            String snsToke = authHelper.getSNSToken(snsAccesstoken, openid, persistentCode);
            //第六步
            JSONObject userInfo = UserHelper.getSNSUserInfo(snsToke);

            if(userInfo == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100024);
            }

            //得到钉钉id
            String dingId = userInfo.getJSONObject("user_info").getString("dingId");
            Map<String, Object> param = new HashMap<>(16);
            param.put("dingId",dingId);

            if (!StringUtil.isEmpty(corpid)) {
                param.put("corpid", corpid);
            }

            param.put("del", 0);

            List<UserEntity> userEntityList = userModel.findEntitys(param);

            if (userEntityList == null || userEntityList.size() < 1) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100004);
            }

            //置入随机数,加强登录安全性
            String nr = MD5Util.EncoderByMd5(StringUtil.getRandomPassword(4,6));
            paasRedisHelper.setValuePermanent(USER_INFO_DIGEST, dingId, nr);
            snsUserInfoVO.setNr(nr);

            // 获取用户所在的公司列表
            List<String> corpIdSet = new ArrayList<>();
            for (UserEntity user : userEntityList) {
                corpIdSet.add(user.getCorpid());
            }
            List<CompanyEntity> companyEntityList = companyModel.getCompanyList(corpIdSet);
            Map<String, CompanyEntity> companyMap = new HashMap<>(companyEntityList.size());
            for (CompanyEntity company : companyEntityList) {
                companyMap.put(company.getCorpid(), company);
            }

            //根据corpid找到公司名称，并且将其设置到modelMap中去
            CompanyEntity company;
            List<SnsCompanyVO> companyList = new ArrayList<>();
            for (UserEntity user : userEntityList) {
                // 新对象需要置值到list，所以在循环内部声明
                SnsCompanyVO companyVO = new SnsCompanyVO();
                company = companyMap.get(user.getCorpid());
                if(company != null && company.getStatus().equals(1) && company.getDel().equals(0)){
                    companyVO.setCorpid(company.getCorpid());
                    companyVO.setCorpName(company.getCorpName());
                    companyVO.setUserId(user.getUserId());
                    companyList.add(companyVO);

                    // 清除网关UserVO缓存, 防止权限/员工/部门变更无法生效
                    String loginUserKey = company.getCorpid() + "____" + user.getUserId();
                    paasRedisHelper.removeValue(RedisPrefixConstant.PAAS_LOGIN_USER_INFO, loginUserKey);
                }
            }
            snsUserInfoVO.setCompanyList(companyList);

        } catch (OApiException e) {
            LOG.error("snsUserInfo错误", e);
            throw new XbbException(e.getErrCode(), e.getErrMsg());
        }

        return snsUserInfoVO;
    }

    @Override
    public SnsUserInfoVO snsUserInfo(String code) throws XbbException {
        return snsUserInfo(code, null);
    }
}
